AddCSLuaFile( "cl_init.lua" )
AddCSLuaFile( "shared.lua" )
include( "shared.lua" )

function ENT:Initialize()
	self:SetNetworkedInt("pos", 0)
	self.StartTime = 0
	self.nCam = 0
	
	//if(!self.eFirstCam) then
	//	self.eFirstCam = nil
	//end
	
	if(!self.tCams) then
		self.tCams = {}
	end
	
	self.tPositions = {}
	self.tAngles = {}
	self.nCams = table.Count(self.tCams)
	self.nPositions = 0
	self.vLastCamPos = Vector(0,0,0)
	
	for i, v in pairs(self.tCams) do
		self.tPositions[self.nPositions] = v:GetPos()
		self.tAngles[self.nPositions] = v:GetAngles()
		self.nPositions = self.nPositions + 1
	end
end

function ENT:OnRemove()
	if(self.on) then
		local ptab = self.pOwner:GetTable() 
		if(ptab.UsingCamera && ptab.UsingCamera == self.eView) then
			self.pOwner:SetViewEntity(self.pOwner)
			self.pOwner:GetTable().UsingCamera = nil
			self:GetTable().UsingPlayer = nil
			self.eView:Remove()
		end
	end
end

function GetPos(nPosition, nLength, vStart, vMiddle, vEnd)
	local nPos = nPosition/nLength
	local nPosTrig = nPos*(math.pi/2)
	
	local vDifference = vMiddle - vStart
	local vDifference2 = vEnd - vMiddle
	
	local nSin = math.sin(nPosTrig)-1
	local nCos = math.cos(nPosTrig)
	
	local nX = vEnd.x-((vDifference2.x*nCos)-(vDifference.x*nSin))
	local nY = vEnd.y-((vDifference2.y*nCos)-(vDifference.y*nSin))
	local nZ = vEnd.z-((vDifference2.z*nCos)-(vDifference.z*nSin))
	
	local vReturn = Vector(nX, nY, nZ)
	
	return vReturn
end

function GetAng(nPosition, nLength, aStart, aMiddle, aEnd)
	local nPos = nPosition/nLength
	local nPosTrig = nPos*(math.pi/2)
	
	local aDifference = aMiddle - aStart
	local aDifference2 = aEnd - aMiddle
	
	local nSin = math.sin(nPosTrig)-1
	local nCos = math.cos(nPosTrig)
	
	local nX = aEnd.p-((aDifference2.p*nCos)-(aDifference.p*nSin))
	local nY = aEnd.y-((aDifference2.y*nCos)-(aDifference.y*nSin))
	local nZ = aEnd.r-((aDifference2.r*nCos)-(aDifference.r*nSin))
	
	local aReturn = Angle(nX, nY, nZ)
	
	return aReturn
end

local function Toggle( pl, ent )
	if (!ent || ent == NULL) then return false end
	
	if(ent.on) then
		ent.on = false
		
		local ptab = pl:GetTable()
		if(ptab.UsingCamera && ptab.UsingCamera == ent.eView) then
 			pl:SetViewEntity(pl)
			pl:GetTable().UsingCamera = nil
			ent:GetTable().UsingPlayer = nil
			ent.eView:Remove()
		end
	else
		ent.StartTime = CurTime()
		ent.on =  true
		
		ent.eView = ents.Create("gmod_cameraprop")
		ent.eView:SetPos(ent:GetPos()+Vector(0,0,16))
		ent.eView:Spawn()
		ent.eView:Activate()
		
		local ptab = pl:GetTable()
		pl:SetViewEntity(ent.eView)
		ptab.UsingCamera = ent.eView
 		ent:GetTable().UsingPlayer = pl
	end
end

numpad.Register("MovingCamera_Toggle", Toggle)

// STEAM_0:1:6705733

function ThinkingHurts()
	local ent = ents.FindByClass("sent_camera_manager")
	for i, v in pairs(ent) do
		if(v.on) then
			if(!v.tPositions[2]) then
				Msg("There are not enough cameras!\n")
				
				local ptab = v.pOwner:GetTable() 
				if(ptab.UsingCamera && ptab.UsingCamera == v.eView) then
					v.pOwner:SetViewEntity(v.pOwner)
					v.pOwner:GetTable().UsingCamera = nil
					v:GetTable().UsingPlayer = nil
					v.eView:Remove()
				end
			else
				local nTime = v:GetNetworkedInt("time")
				local nCam = v.nCam
				
				local vMid1 = (v.tPositions[nCam]+v.tPositions[nCam+1])/2
				local vMid2 = (v.tPositions[nCam+1]+v.tPositions[nCam+2])/2
				
				local aMid1 = (v.tAngles[nCam]+v.tAngles[nCam+1])
				local aMid2 = (v.tAngles[nCam+1]+v.tAngles[nCam+2])
				
				aMid1.p = aMid1.p/2
				aMid1.y = aMid1.y/2
				aMid1.r = aMid1.r/2
				aMid2.p = aMid2.p/2
				aMid2.y = aMid2.y/2
				aMid2.r = aMid2.r/2
				
				if(nCam == 0) then
					vMid1 = v.tPositions[nCam]
					aMid1 = v.tAngles[nCam]
				end
				
				if(nCam == v.nCams-4) then
					vMid2 = v.tPositions[nCam+2]
					aMid2 = v.tAngles[nCam+2]
				end
				
				vPos = GetPos(((CurTime()) - v.StartTime)*(v.nCams), nTime, vMid1, v.tPositions[nCam+1], vMid2)
				aAng = GetAng(((CurTime()) - v.StartTime)*(v.nCams), nTime, aMid1, v.tAngles[nCam+1], aMid2)
				
				if(v.bLookForward == true) then
					local vDifference = vPos-v.vLastCamPos
					aAng = vDifference:Angle()
					v.vLastCamPos = vPos
				end
				
				v.eView:SetPos(vPos)
				v.eView:SetAngles(aAng)
				
				if((CurTime() - v.StartTime) >= nTime/v.nCams) then
					v.StartTime = CurTime()
					v.nCam = v.nCam + 1
					
					if(v.nCam>=v.nCams-3) then
						v.nCam = 0
					end
				end
			end
		end
	end
end

hook.Add("Think", "MovingCamera_Movement", ThinkingHurts)
